﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.DependencyInjection;

namespace StyleMVVM.Data.Activation
{
	/// <summary>
	/// This service creatse and clones objects for interested parties.
	/// The base implementation uses cached compiled Linq Expressions for performance
	/// </summary>
	public interface IActivationService
	{
		/// <summary>
		///  Allows you to override how type is rendered.
		///  Must be set at startup for everything starts.
		/// </summary>
		ITypeAugmenter TypeAugmenter { get; set; }

		/// <summary>
		/// Injects dependencies into an object based on it's attributes.
		/// </summary>
		/// <param name="injectObject"></param>
		void Inject(object injectObject);

		/// <summary>
		/// Injects dependencies into an object based on it's attributes
		/// </summary>
		/// <param name="injectionContext"></param>
		/// <param name="injectObject"></param>
		void Inject(IInjectionContext injectionContext, object injectObject);

		/// <summary>
		/// Creates a new instance of createType
		/// All imports will be satisfied and message handlers registered
		/// </summary>
		/// <param name="injectionContext"></param>
		/// <param name="createType"></param>
		/// <param name="constructorParams"></param>
		/// <returns></returns>
		object CreateByType(IInjectionContext injectionContext, Type createType, params object[] constructorParams);

		/// <summary>
		/// Creates a deep clone of the specified object.
		/// </summary>
		/// <typeparam name="T">Type of object to clone</typeparam>
		/// <param name="cloneValue">object to clone</param>
		/// <returns></returns>
		object DeepClone(object cloneValue);

		/// <summary>
		/// Clone one object into another.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="cloneValue"></param>
		/// <param name="tInstance"></param>
		/// <returns></returns>
		object DeepCloneIntoInstance(object cloneValue, object tInstance);

		/// <summary>
		/// Creates a new activation strategy based on the typeInfo provided.
		/// </summary>
		/// <param name="typeInfo"></param>
		/// <returns></returns>
		IActivationStrategy CreateActivationStrategy(IActivationTypeInfo typeInfo);
	}
}